package com.gss.security.domain;

import java.util.Collection;
import java.util.HashSet;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import com.gss.armory.domain.DepartmentDetailsDTO;
import com.gss.armory.domain.LocationDetailsDTO;
import com.gss.common.domain.CommonDetailsDTO;
import com.gss.common.util.ApplicationMaps;

@Entity
@Table(name = "ARMORY_USER_DETAILS")
public class UserDetailsDTO extends CommonDetailsDTO implements UserDetails {

	private static final long serialVersionUID = 4252923265521334091L;

	private String username;
	private String password;
	private String txtPassword; 
	private boolean isAccountNonExpired;
	private boolean isAccountNonLocked;
	private boolean isCredentialsNonExpired;
	private boolean isEnabled;
	private boolean credentialsExpired;
	private Integer count;

	private String[] role;

	private Collection<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
	private String userDisplayName;
	@NotBlank
	@Email
	private String emailId;
	private Long buId;
	private Long deptId;
	private Integer cdId;
	// private BusinessUnitDetailsDTO userBU;
	private LocationDetailsDTO locationDetailsDTO;
	private DepartmentDetailsDTO userDeptt;
	
	private String deptName;
	private String locName;
	//private CompanyDetailsDTO companyDetailsDTO;

	@Transient
	public boolean isCredentialsExpired() {
		return credentialsExpired;
	}

	public void setCredentialsExpired(boolean credentialsExpired) {
		this.credentialsExpired = credentialsExpired;
	}

	@Column(name = "UD_COUNT", nullable = true)
	public Integer getCount() {
		return count;
	}

	public void setCount(Integer count) {
		this.count = count;
	}

	@ManyToMany(targetEntity = RoleDetailsDTO.class, cascade = CascadeType.DETACH , fetch = FetchType.EAGER)
	@JoinTable(name = "ARMORY_USER_ROLE_MAPPING", joinColumns = @JoinColumn(name = "URM_USER_ID"), inverseJoinColumns = @JoinColumn(name = "URM_ROLE_ID"))
	public Collection<GrantedAuthority> getAuthorities() {

		return authorities;
	}

	@Basic
	@Column(name = "UD_PASSWORD", length = 100, nullable = false)
	public String getPassword() {

		return password;
	}

	@Id
	@Column(name = "UD_USER_ID", length = 20)
	public String getUsername() {

		return username;
	}

	@Column(name = "UD_IS_ACNT_NON_EXPD", nullable = false, columnDefinition = "smallint default 1")
	public boolean isAccountNonExpired() {

		return isAccountNonExpired;
	}

	/*
	 * @Transient public boolean getIsAccountNonExpired() {
	 * 
	 * return isAccountNonExpired; }
	 */

	@Column(name = "UD_IS_ACNT_NON_LOCKD", nullable = false, columnDefinition = "smallint default 1")
	public boolean isAccountNonLocked() {

		return isAccountNonLocked;
	}

	/*
	 * @Transient public boolean getIsAccountNonLocked() {
	 * 
	 * return isAccountNonLocked; }
	 */

	@Column(name = "UD_IS_CRED_NON_EXPD", nullable = false, columnDefinition = "smallint default 1")
	public boolean isCredentialsNonExpired() {

		return isCredentialsNonExpired;
	}

	/*
	 * @Transient public boolean getIsCredentialsNonExpired() {
	 * 
	 * return isCredentialsNonExpired; }
	 */

	@Column(name = "UD_IS_ENABLED", nullable = false, columnDefinition = "smallint default 1")
	public boolean isEnabled() {

		return isEnabled;
	}

	/*
	 * @Transient public boolean getIsEnabled() {
	 * 
	 * return isEnabled; }
	 */

	@Column(name = "UD_USER_NAME", length = 40, nullable = false)
	public String getUserDisplayName() {
		return userDisplayName;
	}

	public void setUserDisplayName(String userDisplayName) {
		this.userDisplayName = userDisplayName;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setAccountNonExpired(boolean isAccountNonExpired) {
		this.isAccountNonExpired = isAccountNonExpired;
	}

	public void setAccountNonLocked(boolean isAccountNonLocked) {
		this.isAccountNonLocked = isAccountNonLocked;
	}

	public void setCredentialsNonExpired(boolean isCredentialsNonExpired) {
		this.isCredentialsNonExpired = isCredentialsNonExpired;
	}

	public void setEnabled(boolean isEnabled) {
		this.isEnabled = isEnabled;
	}

	/*
	 * public void setIsAccountNonExpired(boolean isAccountNonExpired) {
	 * this.isAccountNonExpired = isAccountNonExpired; }
	 * 
	 * public void setIsAccountNonLocked(boolean isAccountNonLocked) {
	 * this.isAccountNonLocked = isAccountNonLocked; }
	 * 
	 * public void setIsCredentialsNonExpired(boolean isCredentialsNonExpired) {
	 * this.isCredentialsNonExpired = isCredentialsNonExpired; }
	 * 
	 * public void setIsEnabled(boolean isEnabled) { this.isEnabled = isEnabled;
	 * }
	 */

	public void setAuthorities(Collection<GrantedAuthority> authorities) {
		this.authorities = authorities;
	}

	@Override
	public String toString() {
		return "UserDetailsDTO [password=" + password
				+ ", userDisplayName=" + userDisplayName + ", username="
				+ username + "]";
	}

	@Column(name = "UD_EMAILID", length = 50)
	public String getEmailId() {
		return emailId;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}

	@Column(name = "UD_LOC_ID")
	public Long getBuId() {
		return buId;
	}

	public void setBuId(Long buId) {
		this.buId = buId;
	}

	@Column(name = "UD_DEPT_ID")
	public Long getDeptId() {
		return deptId;
	}

	public void setDeptId(Long deptId) {
		this.deptId = deptId;
	}
	
	@Column(name = "UD_CD_ID")
	public Integer getCdId() {
		return cdId;
	}

	public void setCdId(Integer cdId) {
		this.cdId = cdId;
	}

	/*
	 * @ManyToOne(targetEntity=BusinessUnitDetailsDTO.class,fetch=FetchType.LAZY)
	 * 
	 * @JoinColumn(name="UD_BU_ID",insertable=false,updatable=false) public
	 * BusinessUnitDetailsDTO getUserBU(){ return userBU; }
	 */

	@ManyToOne(targetEntity = LocationDetailsDTO.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "UD_LOC_ID", insertable = false, updatable = false)
	public LocationDetailsDTO getLocationDetailsDTO() {
		return locationDetailsDTO;
	}

	@ManyToOne(targetEntity = DepartmentDetailsDTO.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "UD_DEPT_ID", insertable = false, updatable = false)
	public DepartmentDetailsDTO getUserDeptt() {
		return userDeptt;
	}

	public void setLocationDetailsDTO(LocationDetailsDTO locationDetailsDTO) {
		this.locationDetailsDTO = locationDetailsDTO;
	}

	/*@ManyToOne(targetEntity = CompanyDetailsDTO.class, fetch = FetchType.LAZY)
	@JoinColumn(name = "UD_CD_ID",insertable = false, updatable = false)
	public CompanyDetailsDTO getCompanyDetailsDTO() {
		return companyDetailsDTO;
	}

	public void setCompanyDetailsDTO(CompanyDetailsDTO companyDetailsDTO) {
		this.companyDetailsDTO = companyDetailsDTO;
	}*/
	
	/*
	 * public void setUserBU(BusinessUnitDetailsDTO userBU) { this.userBU =
	 * userBU; }
	 */

	public void setUserDeptt(DepartmentDetailsDTO userDeptt) {
		this.userDeptt = userDeptt;
	}

	public void setRole(String[] role) {
		this.role = role;
	}

	@Transient
	public String[] getRole() {
		return role;
	}
	
	@Transient
	public String getDeptName() {
		if(null != deptId)
			return ApplicationMaps.DEPTID_DEPTSNAME_MAP.get(deptId);
		else
			return "";
	}

	@Transient
	public String getLocName() {
		if(null != buId)
			return ApplicationMaps.LOCID_LOCNAME_MAP.get(buId);
		else
			return "";
	}

	@Transient
	public String getTxtPassword() {
		return txtPassword;
	}

	public void setTxtPassword(String txtPassword) {
		this.txtPassword = txtPassword;
	}
}
